//
//------------------------------------------------------------------------------
//     Copyright (c) 2017 Huawei Technologies Co., Ltd. All Rights Reserved.
//
//     This program is free software; you can redistribute it and/or modify
//     it under the terms of the Huawei Software License (the "License").
//     A copy of the License is located in the "LICENSE" file accompanying 
//     this file.
//
//     This program is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//     Huawei Software License for more details. 
//------------------------------------------------------------------------------


`resetall
// synopsys translate_off
`timescale 1 ns / 1 ps
// synopsys translate_on
module xilinx_sdpramb_sclk
    #(
    parameter       DEVICE_MODE     = "SPARTAN6",         //
    parameter       RAM_TYPE        = "36Kb",             //"9Kb" or "18Kb" or "36Kb"
    parameter       WRITE_WIDTH     = 8,                  //WRITE_DATA WIDTH
    parameter       WRITE_DEPTHBIT  = 10,                 //WRITE_RAM ADDR WIDTH
    parameter       READ_WIDTH      = 8,                  //READ_DATA WIDTH
    parameter       READ_DEPTHBIT   = 10,                 //WRITE_RAM ADDR WIDTH
    parameter       RAM_OUT_REG     = 1,                  //OUTPUT NOT REGISTER,1 is register
    parameter       R_W_TYPE_MIX    = "WRITE_FIRST"       //WRITE_FIRST or READ_FIRST
    )
    (
    input   wire                            clock,         //
    input   wire                            enable,        //
    input   wire                            wren,          //
    input   wire    [WRITE_DEPTHBIT-1:0]    wraddress,     //
    input   wire    [WRITE_WIDTH-1:0]       data,          //
    input   wire    [READ_DEPTHBIT-1:0]     rdaddress,     //
    output  wire    [READ_WIDTH-1:0]        q              //
	);
/**********************************************************************************************************************\
    parameters declaration
\**********************************************************************************************************************/

localparam MAX_DATA_WIDTH    = max_ram_data_width(WRITE_WIDTH,WRITE_DEPTHBIT);

localparam MAX_RD_DATA_WIDTH = max_ram_data_width(READ_WIDTH,READ_DEPTHBIT);

localparam MOD_WIDTH        = WRITE_WIDTH % MAX_DATA_WIDTH;
//localparam TRUE_MOD_WIDTH = true_mod_width(MOD_WIDTH,WRITE_WIDTH,MAX_DATA_WIDTH );
//localparam RAM_CNT        = ram_count(WRITE_WIDTH,TRUE_MOD_WIDTH,MAX_DATA_WIDTH);
localparam RAM_CNT          = ram_count(WRITE_WIDTH,MOD_WIDTH,MAX_DATA_WIDTH);
localparam WE_WIDTH_1       = we_width(MAX_DATA_WIDTH);
localparam WE_WIDTH_2       = we_width(WRITE_WIDTH-MAX_DATA_WIDTH*RAM_CNT);
localparam OTHER_WIDTH_WR1  = address_other_cal(MAX_DATA_WIDTH);
localparam OTHER_WIDTH_WR2  = address_other_cal(WRITE_WIDTH-MAX_DATA_WIDTH*RAM_CNT);
localparam OTHER_WIDTH_RD1  = address_other_cal(MAX_RD_DATA_WIDTH);
localparam OTHER_WIDTH_RD2  = address_other_cal(READ_WIDTH-MAX_RD_DATA_WIDTH*RAM_CNT);

localparam ADDR_WIDTH_WR1   = OTHER_WIDTH_WR1 - WRITE_DEPTHBIT;
localparam ADDR_WIDTH_WR2   = OTHER_WIDTH_WR2 - WRITE_DEPTHBIT;
localparam ADDR_WIDTH_RD1   = OTHER_WIDTH_RD1 - READ_DEPTHBIT;
localparam ADDR_WIDTH_RD2   = OTHER_WIDTH_RD2 - READ_DEPTHBIT;


/**********************************************************************************************************************\
    variables type declaration
\**********************************************************************************************************************/


/**********************************************************************************************************************\
    main code
\**********************************************************************************************************************/
   ///////////////////////////////////////////////////////////////////////
   //  READ_WIDTH | BRAM_SIZE | READ Depth  | RDADDR Width |            //
   // WRITE_WIDTH |           | WRITE Depth | WRADDR Width |  WE Width  //
   // ============|===========|=============|==============|============//
   //    37-72    |  "36Kb"   |      512    |     9-bit    |    8-bit   //
   //    19-36    |  "36Kb"   |     1024    |    10-bit    |    4-bit   //
   //    10-18    |  "36Kb"   |     2048    |    11-bit    |    2-bit   //
   //     5-9     |  "36Kb"   |     4096    |    12-bit    |    1-bit   //
   //     3-4     |  "36Kb"   |     8192    |    13-bit    |    1-bit   //
   //       2     |  "36Kb"   |    16384    |    14-bit    |    1-bit   //
   //       1     |  "36Kb"   |    32768    |    15-bit    |    1-bit   //
   //    19-36    |  "18Kb"   |      512    |     9-bit    |    4-bit   //
   //    10-18    |  "18Kb"   |     1024    |    10-bit    |    2-bit   //
   //     5-9     |  "18Kb"   |     2048    |    11-bit    |    1-bit   //
   //     3-4     |  "18Kb"   |     4096    |    12-bit    |    1-bit   //
   //       2     |  "18Kb"   |     8192    |    13-bit    |    1-bit   //
   //       1     |  "18Kb"   |    16384    |    14-bit    |    1-bit   //
   //    10-18    |   "9Kb"   |      512    |     9-bit    |    2-bit   //
   //     5-9     |   "9Kb"   |     1024    |    10-bit    |    1-bit   //
   //     3-4     |   "9Kb"   |     2048    |    11-bit    |    1-bit   //
   //       2     |  " 9Kb"   |     4096    |    12-bit    |    1-bit   //
   //       1     |   "9Kb"   |     8192    |    13-bit    |    1-bit   //
   ///////////////////////////////////////////////////////////////////////

//**********************************************************************************************************************

generate
genvar i;
begin
    for ( i=0; i<=RAM_CNT; i=i+1 )
    begin: sdpram
        if ( i == RAM_CNT )
        begin
            BRAM_SDP_MACRO
            #(
            .BRAM_SIZE (RAM_TYPE ), // Target BRAM, "9Kb" or "18Kb"
            .DEVICE(DEVICE_MODE     ), // Target device: "VIRTEX5", "VIRTEX6", "SPARTAN6"
            .WRITE_WIDTH(WRITE_WIDTH-MAX_DATA_WIDTH*RAM_CNT),    // Valid values are 1-36
            .READ_WIDTH(READ_WIDTH-MAX_RD_DATA_WIDTH*RAM_CNT),     // Valid values are 1-36
            .DO_REG(RAM_OUT_REG     ),         // Optional output register (0 or 1)
            .INIT_FILE ("NONE"),
            .WRITE_MODE (R_W_TYPE_MIX),
            .SIM_COLLISION_CHECK ("NONE"), // Collision check enable "ALL", "WARNING_ONLY",
                                          //   "GENERATE_X_ONLY" or "NONE"
            .SRVAL(72'h000000000000000000), // Set/Reset value for port output
            .INIT(72'h000000000000000000),  // Initial values on output port
            .INIT_00(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_01(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_02(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_03(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_04(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_05(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_06(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_07(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_08(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_09(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_0A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_0B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_0C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_0D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_0E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_0F(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_10(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_11(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_12(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_13(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_14(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_15(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_16(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_17(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_18(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_19(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_1A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_1B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_1C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_1D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_1E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_1F(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_20(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_21(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_22(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_23(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_24(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_25(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_26(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_27(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_28(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_29(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_2A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_2B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_2C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_2D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_2E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_2F(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_30(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_31(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_32(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_33(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_34(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_35(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_36(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_37(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_38(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_39(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_3A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_3B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_3C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_3D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_3E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_3F(256'h0000000000000000000000000000000000000000000000000000000000000000),

            // The next set of INIT_xx are valid when configured as 36Kb
            .INIT_40(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_41(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_42(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_43(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_44(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_45(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_46(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_47(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_48(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_49(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_4A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_4B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_4C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_4D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_4E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_4F(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_50(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_51(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_52(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_53(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_54(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_55(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_56(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_57(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_58(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_59(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_5A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_5B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_5C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_5D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_5E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_5F(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_60(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_61(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_62(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_63(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_64(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_65(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_66(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_67(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_68(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_69(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_6A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_6B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_6C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_6D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_6E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_6F(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_70(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_71(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_72(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_73(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_74(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_75(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_76(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_77(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_78(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_79(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_7A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_7B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_7C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_7D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_7E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_7F(256'h0000000000000000000000000000000000000000000000000000000000000000),

            // The next set of INITP_xx are for the parity bits
            .INITP_00(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_01(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_02(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_03(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_04(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_05(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_06(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_07(256'h0000000000000000000000000000000000000000000000000000000000000000),

            // The next set of INITP_xx are valid when configured as 36Kb
            .INITP_08(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_09(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_0A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_0B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_0C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_0D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_0E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_0F(256'h0000000000000000000000000000000000000000000000000000000000000000)
            ) BRAM_SDP_MACR0_inst
            (
            .DO                         ( q[READ_WIDTH-1:MAX_RD_DATA_WIDTH*i]  ), // Output read data port
            .DI                         ( data[WRITE_WIDTH-1:MAX_DATA_WIDTH*i] ), // Input write data port
            .RDADDR                     ( {{ADDR_WIDTH_RD2{1'b0}},rdaddress} ), // Input read address
            .RDCLK                      ( clock                     ), // Input read clock
            .RDEN                       ( 1'b1                      ), // Input read port enable
            .REGCE                      ( 1'b1                      ), // Input read output register enable
            .RST                        ( 1'b0                      ), // Input reset
            //.WE                         ( {WE_WIDTH_2{1'b1}}        ), // Input write enable
            .WE                         ( {WE_WIDTH_2{wren}}        ), // Input write enable
            .WRADDR                     ( {{ADDR_WIDTH_WR2{1'b0}},wraddress} ), // Input write address
            .WRCLK                      ( clock                     ), // Input write clock
            //.WREN                       ( wren                      )  // Input write port enable
            .WREN                       ( enable                      )  // Input write port enable
            );
        end
        else
        begin
            BRAM_SDP_MACRO
            #(
            .BRAM_SIZE (RAM_TYPE ), // Target BRAM, "9Kb" or "18Kb"
            .DEVICE(DEVICE_MODE     ), // Target device: "VIRTEX5", "VIRTEX6", "SPARTAN6"
            .WRITE_WIDTH(MAX_DATA_WIDTH),    // Valid values are 1-36
            .READ_WIDTH(MAX_RD_DATA_WIDTH),     // Valid values are 1-36
            .DO_REG(RAM_OUT_REG     ),         // Optional output register (0 or 1)
            .INIT_FILE ("NONE"),
            .WRITE_MODE (R_W_TYPE_MIX),
            .SIM_COLLISION_CHECK ("NONE"), // Collision check enable "ALL", "WARNING_ONLY",
                                          //   "GENERATE_X_ONLY" or "NONE"
            .SRVAL(72'h000000000000000000), // Set/Reset value for port output
            .INIT(72'h000000000000000000),  // Initial values on output port
            .INIT_00(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_01(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_02(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_03(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_04(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_05(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_06(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_07(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_08(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_09(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_0A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_0B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_0C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_0D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_0E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_0F(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_10(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_11(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_12(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_13(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_14(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_15(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_16(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_17(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_18(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_19(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_1A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_1B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_1C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_1D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_1E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_1F(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_20(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_21(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_22(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_23(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_24(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_25(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_26(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_27(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_28(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_29(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_2A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_2B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_2C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_2D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_2E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_2F(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_30(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_31(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_32(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_33(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_34(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_35(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_36(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_37(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_38(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_39(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_3A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_3B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_3C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_3D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_3E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_3F(256'h0000000000000000000000000000000000000000000000000000000000000000),

            // The next set of INIT_xx are valid when configured as 36Kb
            .INIT_40(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_41(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_42(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_43(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_44(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_45(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_46(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_47(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_48(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_49(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_4A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_4B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_4C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_4D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_4E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_4F(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_50(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_51(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_52(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_53(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_54(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_55(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_56(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_57(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_58(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_59(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_5A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_5B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_5C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_5D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_5E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_5F(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_60(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_61(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_62(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_63(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_64(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_65(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_66(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_67(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_68(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_69(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_6A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_6B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_6C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_6D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_6E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_6F(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_70(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_71(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_72(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_73(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_74(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_75(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_76(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_77(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_78(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_79(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_7A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_7B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_7C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_7D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_7E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INIT_7F(256'h0000000000000000000000000000000000000000000000000000000000000000),

            // The next set of INITP_xx are for the parity bits
            .INITP_00(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_01(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_02(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_03(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_04(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_05(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_06(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_07(256'h0000000000000000000000000000000000000000000000000000000000000000),

            // The next set of INITP_xx are valid when configured as 36Kb
            .INITP_08(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_09(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_0A(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_0B(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_0C(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_0D(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_0E(256'h0000000000000000000000000000000000000000000000000000000000000000),
            .INITP_0F(256'h0000000000000000000000000000000000000000000000000000000000000000)
            ) BRAM_SDP_MACR1_inst
            (
            .DO                         ( q[MAX_RD_DATA_WIDTH*(i+1)-1:MAX_RD_DATA_WIDTH*i] ), // Output read data port
            .DI                         ( data[MAX_DATA_WIDTH*(i+1)-1:MAX_DATA_WIDTH*i] ), // Input write data port
            .RDADDR                     ( {{ADDR_WIDTH_RD1{1'b0}},rdaddress} ), // Input read address
            .RDCLK                      ( clock                     ), // Input read clock
            .RDEN                       ( 1'b1                      ), // Input read port enable
            .REGCE                      ( 1'b1                      ), // Input read output register enable
            .RST                        ( 1'b0                      ), // Input reset
            //.WE                         ( {WE_WIDTH_1{1'b1}}        ), // Input write enable
            .WE                         ( {WE_WIDTH_1{wren}}        ), // Input write enable
            .WRADDR                     ( {{ADDR_WIDTH_WR1{1'b0}},wraddress} ), // Input write address
            .WRCLK                      ( clock                     ), // Input write clock
            //.WREN                       ( wren                      )  // Input write port enable
            .WREN                       ( enable                      )  // Input write port enable
            );
        end
    end
end

endgenerate
   // End of BRAM_SDP_MACRO_inst instantiation


//**********************************************************************************************************************
//    the function define
//**********************************************************************************************************************
// because the xilinx's ram can include any width and any depth. so I must
// calculate the different width and depth use different count RAM.



//function integer depth2log;
//    input [31:0] depth ;
//    integer j ;
//
//    begin
//        depth2log = 0;
//        for ( j = 0; 2 ** j <= depth; j = j + 1 )
//        begin
//            depth2log = j;
//        end
//    end
//endfunction


// 2012-1-29 
///////////////////////////////////////////////////////////////////////
//  READ_WIDTH | BRAM_SIZE | READ Depth  | RDADDR Width |            //
// WRITE_WIDTH |           | WRITE Depth | WRADDR Width |  WE Width  //
// ============|===========|=============|==============|============//
//    37-72    |  "36Kb"   |      512    |     9-bit    |    8-bit   //
//    19-36    |  "36Kb"   |     1024    |    10-bit    |    4-bit   //
//    10-18    |  "36Kb"   |     2048    |    11-bit    |    2-bit   //
//     5-9     |  "36Kb"   |     4096    |    12-bit    |    1-bit   //
//     3-4     |  "36Kb"   |     8192    |    13-bit    |    1-bit   //
//       2     |  "36Kb"   |    16384    |    14-bit    |    1-bit   //
//       1     |  "36Kb"   |    32768    |    15-bit    |    1-bit   //
//    19-36    |  "18Kb"   |      512    |     9-bit    |    4-bit   //
//    10-18    |  "18Kb"   |     1024    |    10-bit    |    2-bit   //
//     5-9     |  "18Kb"   |     2048    |    11-bit    |    1-bit   //
//     3-4     |  "18Kb"   |     4096    |    12-bit    |    1-bit   //
//       2     |  "18Kb"   |     8192    |    13-bit    |    1-bit   //
//       1     |  "18Kb"   |    16384    |    14-bit    |    1-bit   //
//    10-18    |   "9Kb"   |      512    |     9-bit    |    2-bit   //
//     5-9     |   "9Kb"   |     1024    |    10-bit    |    1-bit   //
//     3-4     |   "9Kb"   |     2048    |    11-bit    |    1-bit   //
//       2     |  " 9Kb"   |     4096    |    12-bit    |    1-bit   //
//       1     |   "9Kb"   |     8192    |    13-bit    |    1-bit   //
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////

function integer max_ram_data_width;
    input [31:0] data_width;
    input [31:0] depthbits;
    //input  ram_type;

    begin
        if ( RAM_TYPE == "36Kb" )
        begin
            if ( depthbits[3:0] <= 4'h9 )
            begin
                if ( data_width[31:0] < 32'd72 )
                    max_ram_data_width = data_width;
                else
                    max_ram_data_width = 72;
            end
            else if ( depthbits[3:0] == 4'ha )
            begin
                if ( data_width[31:0] < 32'd36 )
                    max_ram_data_width = data_width;
                else
                    max_ram_data_width = 36;
            end
            else if ( depthbits[3:0] == 4'hb )
            begin
                if ( data_width[31:0] < 32'd18 )
                    max_ram_data_width = data_width;
                else
                    max_ram_data_width = 18;
            end
            else if ( depthbits[3:0] == 4'hc )
            begin
                if ( data_width[31:0] < 32'd9 )
                    max_ram_data_width = data_width;
                else
                    max_ram_data_width = 9;
            end
            else if ( depthbits[3:0] == 4'hd )
            begin
                if ( data_width[31:0] < 32'd4 )
                    max_ram_data_width = data_width;
                else
                    max_ram_data_width = 4;
            end
            else if ( depthbits[3:0] == 4'he )
            begin
                if ( data_width[31:0] < 32'd2 )
                    max_ram_data_width = data_width;
                else
                    max_ram_data_width = 2;
            end
            else
                max_ram_data_width = 1;
        end
        else if ( RAM_TYPE == "18Kb" )
        begin
            if ( depthbits[3:0] <= 4'h9 )
            begin
                if ( data_width[31:0] < 32'd36 )
                    max_ram_data_width = data_width;
                else
                    max_ram_data_width = 36;
            end
            else if ( depthbits[3:0] == 4'ha )
            begin
                if ( data_width[31:0] < 32'd18 )
                    max_ram_data_width = data_width;
                else
                    max_ram_data_width = 18;
            end
            else if ( depthbits[3:0] == 4'hb )
            begin
                if ( data_width[31:0] < 32'd9 )
                    max_ram_data_width = data_width;
                else
                    max_ram_data_width = 9;
            end
            else if ( depthbits[3:0] == 4'hc )
            begin
                if ( data_width[31:0] < 32'd4 )
                    max_ram_data_width = data_width;
                else
                    max_ram_data_width = 4;
            end
            else if ( depthbits[3:0] == 4'hd )
            begin
                if ( data_width[31:0] < 32'd2 )
                    max_ram_data_width = data_width;
                else
                    max_ram_data_width = 2;
            end
            else
                max_ram_data_width = 1;
        end
        else
        begin
            if ( depthbits[3:0] <= 4'h9 )
            begin
                if ( data_width[31:0] < 32'd18 )
                    max_ram_data_width = data_width;
                else
                    max_ram_data_width = 18;
            end
            else if ( depthbits[3:0] == 4'ha )
            begin
                if ( data_width[31:0] < 32'd9 )
                    max_ram_data_width = data_width;
                else
                    max_ram_data_width = 9;
            end
            else if ( depthbits[3:0] == 4'hb )
            begin
                if ( data_width[31:0] < 32'd4 )
                    max_ram_data_width = data_width;
                else
                    max_ram_data_width = 4;
            end
            else if ( depthbits[3:0] == 4'hc )
            begin
                if ( data_width[31:0] < 32'd2 )
                    max_ram_data_width = data_width;
                else
                    max_ram_data_width = 2;
            end
            else
                max_ram_data_width = 1;
        end
    end
endfunction

//function integer true_mod_width;
//    input  mod_width;
//    input  data_width;
//    input  max_ram_data_width;
//
//    begin
//        if ( data_width == max_ram_data_width )
//            true_mod_width = 1;
//        else
//            true_mod_width = mod_width;
//    end
//
//endfunction

function integer ram_count;
    input [31:0] write_width;
    input [31:0] true_mod;
    input [31:0] max_data_width;

    begin
        if ( true_mod == 0 )
            ram_count = (write_width / max_data_width) - 1;
        else
            ram_count = write_width / max_data_width;
    end


endfunction


function integer we_width;
    input [31:0] max_data_width;

    begin
        if ( max_data_width < 32'd10 )
            we_width = 1;
        else if ( max_data_width < 32'd19 )
            we_width = 2;
        else if ( max_data_width < 32'd37 )
            we_width = 4;
        else
            we_width = 8;
    end

endfunction

function integer address_other_cal;
    input [31:0] data_width;

    begin
        if ( RAM_TYPE == "36Kb" )
        begin
            if ( data_width == 32'd1 )
                address_other_cal = 15;
            else if ( data_width == 32'd2 )
                address_other_cal = 14;
            else if ( data_width <= 32'd4 )
                address_other_cal = 13;
            else if ( data_width <= 32'd9 )
                address_other_cal = 12;
            else if ( data_width <= 32'd18 )
                address_other_cal = 11;
            else if ( data_width <= 32'd36 )
                address_other_cal = 10;
            else
                address_other_cal = 9;
        end
        else if ( RAM_TYPE == "18Kb" )
        begin
            if ( data_width == 32'd1 )
                address_other_cal = 14;
            else if ( data_width == 32'd2 )
                address_other_cal = 13;
            else if ( data_width <= 32'd4 )
                address_other_cal = 12;
            else if ( data_width <= 32'd9 )
                address_other_cal = 11;
            else if ( data_width <= 32'd18 )
                address_other_cal = 10;
            else
                address_other_cal = 9;
        end
        else
        begin
            if ( data_width == 32'd1 )
                address_other_cal = 13;
            else if ( data_width == 32'd2 )
                address_other_cal = 12;
            else if ( data_width <= 32'd4 )
                address_other_cal = 11;
            else if ( data_width <= 32'd9 )
                address_other_cal = 10;
            else
                address_other_cal = 9;
        end
    end

endfunction

endmodule
